package com.hkts.naturalgas.flow.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkts.naturalgas.feign.FeignInterface;
import com.hkts.naturalgas.flow.VO.FLowTemplateInfoVo;
import com.hkts.naturalgas.flow.VO.FlowNodeinfoVo;
import com.hkts.naturalgas.flow.entity.FlowTemplateinfo;
import com.hkts.naturalgas.flow.entity.FlowUserinfo;
import com.hkts.naturalgas.flow.mapper.FlowTemplateinfoMapper;
import com.hkts.naturalgas.flow.mapper.FlowUserinfoMapper;
import com.hkts.naturalgas.flow.service.IFlowNodeinfoService;
import com.hkts.naturalgas.flow.service.IFlowTemplateinfoService;
import com.hkts.naturalgas.flow.service.IFlowUserinfoService;
import com.hkts.naturalgas.organizational.mapper.HontUserMapper;
import com.hkts.naturalgas.organizational.mapper.HontUserRoleMapper;
import com.hkts.naturalgas.organizational.orgVo.HontUserRolelevelQueryVo;
import com.hkts.naturalgas.organizational.service.IHontUserService;
import com.hkts.naturalgas.performance.performanceTo.HontUserTo;
import com.hkts.naturalgas.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * <p>
 * 流程模板表 服务实现类
 * </p>
 *
 * @author zy
 * @since 2022-08-31
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class FlowTemplateinfoServiceImpl extends ServiceImpl<FlowTemplateinfoMapper, FlowTemplateinfo> implements IFlowTemplateinfoService {


    @Autowired
    private FlowTemplateinfoMapper flowTemplateinfoMapper;
    @Autowired
    private IFlowUserinfoService iFlowUserinfoService;
    @Autowired
    private IFlowNodeinfoService iFlowNodeinfoService;
    @Autowired
    private HontUserMapper hontUserMapper;
    @Autowired
    private FeignInterface feignInterface;
    @Autowired
    private HontUserRoleMapper hontUserRoleMapper;


    @Override
    public IPage<FlowTemplateinfo> selectPage(Page<FlowTemplateinfo> page, FlowTemplateinfo flowTemplateinfo) {
        QueryWrapper<FlowTemplateinfo> query = Wrappers.query();
        query.lambda().like(StringUtils.isNotBlank(flowTemplateinfo.getTemplateName()), FlowTemplateinfo::getTemplateName,flowTemplateinfo.getTemplateName())
                .eq(FlowTemplateinfo::getFlowType,flowTemplateinfo.getFlowType());
        QueryWrapper<FlowTemplateinfo> entityWrapper = getEntityWrapper(query, flowTemplateinfo);
        return flowTemplateinfoMapper.selectPage(page, query);
    }
    @Override
    public List<FlowTemplateinfo> selectList(FlowTemplateinfo flowTemplateinfo) {
        HontUserTo u = feignInterface.remoteUserInfo();
        String roles=hontUserRoleMapper.getByUserId(u.getId()).getHontRoleId();
        log.info("获取当前权限的流程列表参数，用户id{},角色{}，部门{}",u.getId(),roles,u.getDepartmentId());
        List<FlowTemplateinfo> flowTemplateinfos=flowTemplateinfoMapper.getTemplateListByAuth(u.getId(),roles,u.getDepartmentId());
        return flowTemplateinfos;
    }

    @Override
    public Map<Integer, List<FlowTemplateinfo>> selectListByOvertime() {
        HontUserTo u = feignInterface.remoteUserInfo();
        String roles=hontUserRoleMapper.getByUserId(u.getId()).getHontRoleId();
        log.info("获取当前权限的流程列表参数，用户id{},角色{}，部门{}",u.getId(),roles,u.getDepartmentId());
        List<FlowTemplateinfo> flowTemplateinfos=flowTemplateinfoMapper.getTemplateListByOvertimeAuth(u.getId(),roles,u.getDepartmentId());
        Map<Integer, List<FlowTemplateinfo>> collect = flowTemplateinfos.stream().collect(groupingBy(FlowTemplateinfo::getFlowType));
        return collect;
    }

    @Override
    public void updateFlowTemplateinfo(FlowTemplateinfo flowTemplateinfo) {
        flowTemplateinfoMapper.updateById(flowTemplateinfo);
    }

    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<FlowTemplateinfo> getEntityWrapper(QueryWrapper<FlowTemplateinfo> entityWrapper, FlowTemplateinfo flowTemplateinfo) {
        entityWrapper.lambda().eq(FlowTemplateinfo::getStatus,1);
        return entityWrapper;
    }

    @Override
    public Result<Object> addFlowTemplateinfo(FLowTemplateInfoVo flowTemplateinfoVo) {
        String id=String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
        String templateVersion=DateUtils.getCurrentDateTimeShort();
        //考核发起人
        List<FlowUserinfo> assessUserInfos=flowTemplateinfoVo.getAssessUserInfos();
        List<FlowUserinfo> assessDepartUserInfos=flowTemplateinfoVo.getAssessDepartUserInfos();
        List<FlowUserinfo> assessRoleUserInfos=flowTemplateinfoVo.getAssessRoleUserInfos();
        iFlowUserinfoService.addFlowUserinfos(assessDepartUserInfos,id,templateVersion,FlowUserinfo.USER_TYPE_DEPART,FlowUserinfo.DATA_TYPE_ACCESS);
        iFlowUserinfoService.addFlowUserinfos(assessRoleUserInfos,id,templateVersion,FlowUserinfo.USER_TYPE_ROLE,FlowUserinfo.DATA_TYPE_ACCESS);
        iFlowUserinfoService.addFlowUserinfos(assessUserInfos,id,templateVersion,FlowUserinfo.USER_TYPE_USER,FlowUserinfo.DATA_TYPE_ACCESS);
        //被考核人
        List<FlowUserinfo> beingAssessUserInfos=flowTemplateinfoVo.getBeingAssessUserInfos();
        List<FlowUserinfo> beingAssessDepartUserInfos=flowTemplateinfoVo.getBeingAssessDepartUserInfos();
        List<FlowUserinfo> beingAssessRoleUserInfos=flowTemplateinfoVo.getBeingAssessRoleUserInfos();
        iFlowUserinfoService.addFlowUserinfos(beingAssessDepartUserInfos,id,templateVersion,FlowUserinfo.USER_TYPE_DEPART,FlowUserinfo.DATA_TYPE_BEINGACCESS);
        iFlowUserinfoService.addFlowUserinfos(beingAssessRoleUserInfos,id,templateVersion,FlowUserinfo.USER_TYPE_ROLE,FlowUserinfo.DATA_TYPE_BEINGACCESS);
        iFlowUserinfoService.addFlowUserinfos(beingAssessUserInfos,id,templateVersion,FlowUserinfo.USER_TYPE_USER,FlowUserinfo.DATA_TYPE_BEINGACCESS);
        //抄送
        List<FlowUserinfo> ccRoleList=flowTemplateinfoVo.getCcRoleList();
        List<FlowUserinfo> ccPersonnelList=flowTemplateinfoVo.getCcPersonnelList();
        iFlowUserinfoService.addFlowUserinfos(ccRoleList,id,templateVersion,FlowUserinfo.USER_TYPE_ROLE,FlowUserinfo.DATA_TYPE_COPY);
        iFlowUserinfoService.addFlowUserinfos(ccPersonnelList,id,templateVersion,FlowUserinfo.USER_TYPE_USER,FlowUserinfo.DATA_TYPE_COPY);
        //节点数据
        List<FlowNodeinfoVo> flowNodeinfoVos=flowTemplateinfoVo.getFlowNodeinfoVos();
        iFlowNodeinfoService.addFlowNodeinfo(flowNodeinfoVos,id,templateVersion);
        //添加模板数据
        long count= beingAssessUser(beingAssessUserInfos,beingAssessDepartUserInfos,beingAssessRoleUserInfos);
        FlowTemplateinfo flowTemplateinfo= BeanConvertUtils.copy(flowTemplateinfoVo,
                FlowTemplateinfo.class);
        flowTemplateinfo.setId(id);
        flowTemplateinfo.setParticipation((int)count);
        flowTemplateinfo.setTemplateVersion(templateVersion);
        flowTemplateinfoMapper.insert(flowTemplateinfo);
        return ResultUtil.success("");
    }
    public long beingAssessUser(List<FlowUserinfo> beingAssessUserInfos,List<FlowUserinfo> beingAssessDepartUserInfos,List<FlowUserinfo> beingAssessRoleUserInfos){
        long count=beingAssessUserInfos.size();
        if(beingAssessRoleUserInfos.size()>0){
            List<String> roleIds=beingAssessRoleUserInfos.stream().map(t->t.getUserRoleId()).collect(Collectors.toList());
            List<String> departs=beingAssessDepartUserInfos.stream().map(t->t.getUserRoleId()).collect(Collectors.toList());
            HontUserRolelevelQueryVo hontUserRolelevelQueryVo=new HontUserRolelevelQueryVo();
            hontUserRolelevelQueryVo.setRoleIds(roleIds);
            hontUserRolelevelQueryVo.setDepartmentIds(departs);
            count+= hontUserMapper.getUserByDepartAndRole(hontUserRolelevelQueryVo).size();
        }
        return count;
    }
    @Override
    public Result<Object> editFlowTemplateinfo(FLowTemplateInfoVo flowTemplateinfoVo) {
//        QueryWrapper<FlowUserinfo> query = Wrappers.query();
//        query.lambda().eq(FlowUserinfo::getTemplateId,flowTemplateinfoVo.getId());
//        iFlowUserinfoService.remove(query);
        flowTemplateinfoVo.setTemplateVersion(DateUtils.getCurrentDateTimeShort());
        //考核发起人
        List<FlowUserinfo> assessUserInfos=flowTemplateinfoVo.getAssessUserInfos();
        List<FlowUserinfo> assessDepartUserInfos=flowTemplateinfoVo.getAssessDepartUserInfos();
        List<FlowUserinfo> assessRoleUserInfos=flowTemplateinfoVo.getAssessRoleUserInfos();
        iFlowUserinfoService.addFlowUserinfos(assessDepartUserInfos,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_DEPART,FlowUserinfo.DATA_TYPE_ACCESS);
        iFlowUserinfoService.addFlowUserinfos(assessRoleUserInfos,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_ROLE,FlowUserinfo.DATA_TYPE_ACCESS);
        iFlowUserinfoService.addFlowUserinfos(assessUserInfos,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_USER,FlowUserinfo.DATA_TYPE_ACCESS);
        //被考核人
        List<FlowUserinfo> beingAssessUserInfos=flowTemplateinfoVo.getBeingAssessUserInfos();
        List<FlowUserinfo> beingAssessDepartUserInfos=flowTemplateinfoVo.getBeingAssessDepartUserInfos();
        List<FlowUserinfo> beingAssessRoleUserInfos=flowTemplateinfoVo.getBeingAssessRoleUserInfos();
        iFlowUserinfoService.addFlowUserinfos(beingAssessDepartUserInfos,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_DEPART,FlowUserinfo.DATA_TYPE_BEINGACCESS);
        iFlowUserinfoService.addFlowUserinfos(beingAssessRoleUserInfos,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_ROLE,FlowUserinfo.DATA_TYPE_BEINGACCESS);
        iFlowUserinfoService.addFlowUserinfos(beingAssessUserInfos,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_USER,FlowUserinfo.DATA_TYPE_BEINGACCESS);
        //抄送
        List<FlowUserinfo> ccRoleList=flowTemplateinfoVo.getCcRoleList();
        List<FlowUserinfo> ccPersonnelList=flowTemplateinfoVo.getCcPersonnelList();
        iFlowUserinfoService.addFlowUserinfos(ccRoleList,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_ROLE,FlowUserinfo.DATA_TYPE_COPY);
        iFlowUserinfoService.addFlowUserinfos(ccPersonnelList,flowTemplateinfoVo.getId(),flowTemplateinfoVo.getTemplateVersion(),FlowUserinfo.USER_TYPE_USER,FlowUserinfo.DATA_TYPE_COPY);
        //节点数据
        List<FlowNodeinfoVo> flowNodeinfoVos=flowTemplateinfoVo.getFlowNodeinfoVos();
        FlowTemplateinfo flowTemplateinfo= BeanConvertUtils.copy(flowTemplateinfoVo,
                FlowTemplateinfo.class);
        iFlowNodeinfoService.addFlowNodeinfo(flowNodeinfoVos,flowTemplateinfo.getId(),flowTemplateinfo.getTemplateVersion());
        long count= beingAssessUser(beingAssessUserInfos,beingAssessDepartUserInfos,beingAssessRoleUserInfos);
        flowTemplateinfo.setParticipation((int)count);
        flowTemplateinfoMapper.updateById(flowTemplateinfo);
        return ResultUtil.success("");
    }

    @Override
    public Result<Object> getFlowTemplateinfo(String templateId) {
        FlowTemplateinfo flowTemplateinfo=  flowTemplateinfoMapper.selectById(templateId);
        FlowUserinfo flowUserinfo=new FlowUserinfo();
        flowUserinfo.setTemplateId(templateId);
        flowUserinfo.setTemplateVersion(flowTemplateinfo.getTemplateVersion());
        List<FlowUserinfo> flowUserinfos=iFlowUserinfoService.selectList(flowUserinfo) ;
        List<FlowNodeinfoVo> flowNodeinfoVos=iFlowNodeinfoService.getFlowNodeinfoVo(templateId,flowTemplateinfo.getTemplateVersion());
        FLowTemplateInfoVo fLowTemplateInfoVo=BeanConvertUtils.copy(flowTemplateinfo,FLowTemplateInfoVo.class);
        fLowTemplateInfoVo.setFlowNodeinfoVos(flowNodeinfoVos);
        fLowTemplateInfoVo.setAssessDepartUserInfos(flowUserinfos.stream().filter(t->
             FlowUserinfo.USER_TYPE_DEPART.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_ACCESS.equals(t.getDataType())
        ).collect(Collectors.toList()));
        fLowTemplateInfoVo.setAssessRoleUserInfos(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_ROLE.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_ACCESS.equals(t.getDataType())
        ).collect(Collectors.toList()));
        fLowTemplateInfoVo.setAssessUserInfos(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_USER.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_ACCESS.equals(t.getDataType())
        ).collect(Collectors.toList()));

        fLowTemplateInfoVo.setBeingAssessDepartUserInfos(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_DEPART.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_BEINGACCESS.equals(t.getDataType())
        ).collect(Collectors.toList()));
        fLowTemplateInfoVo.setBeingAssessRoleUserInfos(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_ROLE.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_BEINGACCESS.equals(t.getDataType())
        ).collect(Collectors.toList()));
        fLowTemplateInfoVo.setBeingAssessUserInfos(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_USER.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_BEINGACCESS.equals(t.getDataType())
        ).collect(Collectors.toList()));

        fLowTemplateInfoVo.setCcRoleList(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_ROLE.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_COPY.equals(t.getDataType())
        ).collect(Collectors.toList()));
        fLowTemplateInfoVo.setCcPersonnelList(flowUserinfos.stream().filter(t->
                FlowUserinfo.USER_TYPE_USER.equals(t.getUserType())&&FlowUserinfo.DATA_TYPE_COPY.equals(t.getDataType())
        ).collect(Collectors.toList()));
        return ResultUtil.data(fLowTemplateInfoVo);
    }
}
